import argparse
import datetime
import threading

import flask
from flask import request
import tensorflow
import numpy
import logging
import schedule
from keras.backend import switch

import token_util

app = flask.Flask(__name__)
model = None
use_gpu = False
token =None

def init():
    global model
    path = './weights/myopia_best_weights.h5'
    if use_gpu:
        tensorflow.configure_run_time_settings(device_policy='CPU')
    model = tensorflow.keras.models.load_model(path)
    refresh_token()
    thread = threading.Thread(target=run_schedule)
    thread.start()

def run_schedule():
    schedule.every(1).day.at("00:01").do(refresh_token)
    while True:
        schedule.run_pending()

def refresh_token():
    global token
    token = token_util.generate_token("-myopia")
    print("refresh token:{}".format(token))

def parse_args():
    parse = argparse.ArgumentParser()
    parse.add_argument('--configs', dest='configs', type=str,
                        default='./configs/default.py',)
    return parse.parse_args()

@app.route("/model/myopia/predict",methods = ["POST","GET"])
def predict():
    print("ip:{} , token:{} , params : {}".format(request.remote_addr, request.headers.get('token'),str(request.form)))
    request_token = request.headers.get('token')
    if not token == request_token:
        return flask.jsonify(str({'code':201,'message':'token error'}))
    data = {'code':400,'message':'预测失败'}
    first_se = request.form.get("first_se").strip()
    first_age = request.form.get("first_age").strip()
    final_age = request.form.get("final_age").strip()
    monthly_se = request.form.get("monthly_se").strip()
    array = numpy.array((first_se, first_age, final_age, monthly_se),dtype=numpy.dtypes.Float64DType).reshape(1,4)
    prediction = model.predict(array)
    if prediction :
        data = {'code':200,'message':'预测成功' , 'data':prediction[0][0]}
    return flask.jsonify(str(data))

@app.route("/model/myopia/predictv2",methods = ["POST","GET"])
def predictv2():
    print("ip:{} , token:{} , params : {}".format(request.remote_addr, request.headers.get('token'),str(request.form)))
    request_token = request.headers.get('token')
    if not token == request_token:
        return flask.jsonify(str({'code':201,'message':'token error'}))
    res = {'code':400,'message':'预测失败'}
    # 获取参数
    birth_day = get_parameters("birth_day")
    first_sd = float(get_parameters("first_sd"))
    first_cd = float(get_parameters("first_cd"))
    first_date = get_parameters("first_date")
    final_sd = float(get_parameters("final_sd"))
    final_cd = float(get_parameters("final_cd"))
    final_date = get_parameters("final_date")
    # predict_age = float(get_parameters("predict_age"))
    format = "%Y-%m-%d"

    if birth_day > first_date or first_date > final_date:
        return flask.jsonify(str({'code':201,'message':'日期有误,请检查您提供的数据'}))

    birth_day = datetime.datetime.strptime(birth_day, format)
    first_date = datetime.datetime.strptime(first_date, format)
    final_date = datetime.datetime.strptime(final_date, format)

    first_se = first_sd + first_cd/2
    first_age = (first_date - birth_day).days/365
    if first_age <0:
        return flask.jsonify(str({'code':201,'message':'日期有误,请检查您提供的数据'}))

    final_se = final_sd + final_cd/2
    final_age = (final_date - birth_day).days/365

    if final_age <0:
        return flask.jsonify(str({'code':201,'message':'日期有误,请检查您提供的数据'}))


    monthly_se = (final_se - first_se) / (final_date.year*12+final_date.month - first_date.year*12 - final_date.month)

    ages =[]
    ses = []
    for i in range(int(final_age) +1 , 21):
        array = numpy.array((first_se, first_age, i, monthly_se),dtype=numpy.dtypes.Float64DType).reshape(1,4)
        prediction = model.predict(array)
        ages.append(i)
        ses.append(round(prediction[0][0],2))


    if ses :
        if ses[-1] < -10.0:
            tip = '您的孩子有极重度近视的风险，请留意孩子的健康成长'
            level = 4
        elif ses[-1] >-10.0 and ses[-1] <-6.0:
            tip = '您的孩子有重度近视的风险，请留意孩子的健康成长'
            level = 3
        elif ses[-1] >-6.0 and ses[-1] <-3.0:
            tip = '您的孩子存在中度近视的可能性'
            level = 2
        else:
            tip = '您的孩子存在轻度近视'
            level = 1

        data = {"ages" : ages,
                "ses" : ses,
                "tip" : tip,
                "level" : level}
        res = {'code':200,'message':'预测成功' , 'data':data}
    return flask.jsonify(str(res))

def get_parameters(name):
    return request.form.get(name).strip()

if __name__ == '__main__':
    print("loading model and start the server")
    init()
    app.run(use_reloader=False, host="0.0.0.0",port=5001,debug=flask)
